<template>
  <div id="blocker" style="width:100%;height: 100%;position: relative">
    <div style="width: 100%;z-index: 99">
      <el-menu :default-active="activeIndex"
               class="el-menu-demo"
               mode="horizontal"
               background-color="#545c64"
               text-color="#fff"
               active-text-color="#ffd04b">
        <el-submenu index="1">
          <template slot="title">画线</template>
          <el-menu-item index="1-1" v-for="(item,index) in options" :key="index" @click="lineClick(item.key)">
            {{item.label}}
          </el-menu-item>
        </el-submenu>
        <el-menu-item index="2" @click="generateBox">生成</el-menu-item>
        <el-menu-item index="3" @click="dragModel">家具</el-menu-item>
        <el-menu-item index="4" @click="textureMapping">材质</el-menu-item>
      </el-menu>
    </div>

    <div style="width: 100%;height: calc(100% - 61px);"
         id="container">
    </div>


    <el-drawer
      title="家具"
      size="100%"
      :visible.sync="drawer"
      :direction="direction"
      :modal="false"
      :wrapperClosable="false"
      style="width: 150px"
      :closeOnClickModal="false">
      <el-image style="width:70px;height: 70px"
                v-for="(url,index) in imgArr"
                :key="index" :src="url.img"
                lazy @dragend="loadingModel"
                @dragstart="passKey(url.key)"></el-image>
      <div style="position: absolute;bottom: 0px;">
        <el-radio-group v-model="radio" @change="controlModeClick">
          <el-radio-button label="移动"></el-radio-button>
          <el-radio-button label="旋转"></el-radio-button>
          <el-radio-button label="缩放"></el-radio-button>
          <el-radio-button label="取消"></el-radio-button>
        </el-radio-group>
      </div>
    </el-drawer>

    <el-drawer
      title="材质"
      size="100%"
      :visible.sync="drawer2"
      :direction="direction2"
      :modal="false"
      :wrapperClosable="false"
      style="width: 150px"
      :closeOnClickModal="false">
      <el-image style="width:140px;height: 140px"
                v-for="(url,index) in textureMappingArr"
                :key="index" :src="url.img"
                lazy @dragend="textureMappingModel"
                @dragstart="textureMappingUrl(url.img)"></el-image>
    </el-drawer>
  </div>
</template>

<script type="module">
  import * as THREE from 'three'
  import { Menu, MenuItem, Submenu, Drawer, MessageBox, Image, RadioGroup, RadioButton } from 'element-ui'
  import Editor from './js/Editor'
  import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
  import { TransformControls } from 'three/examples/jsm/controls/TransformControls'

  const ThreeBSP = require('three-js-csg')(THREE)

  let container, editor
  let renders

  let pointer, raycaster, isShiftDown = false
  //红色方块mesh
  let rollOverMesh, rollOverMaterial
  const objects = []
  let tempLine = null//线
  let lineGroup = new THREE.Group()
  lineGroup.name = 'lineGroup'
  let point1 = new THREE.Vector3()
  let point2 = new THREE.Vector3()
  //保存每点击两次的坐标
  let wall = []
  let theDoor = []
  let theDoorGroup = new THREE.Group()
  theDoorGroup.name = 'theDoorGroup'
  let serArr = new Set()

  //点击次数
  let cnt = 0
  //线条颜色
  let color = ''

  function coordinates () {
    this.point_1 = new THREE.Vector3()
    this.point_2 = new THREE.Vector3()
  }

  //保存model
  let modelArr = []
  //保存材质
  let texture

  let dragModelGroup = new THREE.Group()
  dragModelGroup.name = 'dragModelGroup'
  //key值
  let modelKey
  let textureUrl

  let transformControls = null
  //旋转物体
  let rotateArr = []

  export default {
    name: 'THREETest',
    data () {
      return {
        textureMappingArr: [
          {
            key: 1,
            img: 'http://localhost:3000/file/getFile/three/img/wallImg/t1.jpeg'
          }, {
            key: 2,
            img: 'http://localhost:3000/file/getFile/three/img/wallImg/t2.jpeg'
          }, {
            key: 3,
            img: 'http://localhost:3000/file/getFile/three/img/wallImg/t3.jpeg'
          }, {
            key: 4,
            img: 'http://localhost:3000/file/getFile/three/img/wallImg/t4.jpeg'
          }, {
            key: 5,
            img: 'http://localhost:3000/file/getFile/three/img/wallImg/t5.jpeg'
          }
        ],
        radio: '移动',
        editorModelArr: [],
        direction: 'ltr',
        direction2: 'ltr',
        drawer: false,
        drawer2: false,
        activeIndex: '1',
        options: [{
          key: '1',
          label: '墙壁'
        }, {
          key: '2',
          label: '门'
        }, {
          key: '3',
          label: '窗'
        }, {
          key: '4',
          label: '删线'
        }
        ],
        msg: '',
        imgArr: [
          {
            key: 4,
            img: 'http://localhost:3000/file/getFile/three/table/table2/table.jpg'
          }, {
            key: 5,
            img: 'http://localhost:3000/file/getFile/three/sofa/sofa1/sofa.jpg'
          }, {
            key: 6,
            img: 'http://localhost:3000/file/getFile/three/airConditioner/airConditioner1/airConditioner.jpg'
          }
        ],
      }
    },
    components: {
      ElMenu: Menu,
      ElMenuItem: MenuItem,
      ElSubmenu: Submenu,
      ElDrawer: Drawer,
      ElImage: Image,
      ElRadioGroup: RadioGroup,
      ElRadioButton: RadioButton,
    },
    mounted () {

    },
    methods: {
      adds (url) {
        window.addEventListener('resize', this.onWindowResize, false)//屏幕适应监听
        window.addEventListener('click', this.onWindowResize, false)//屏幕适应监听

        document.addEventListener('keydown', this.onDocumentKeyDown, false)
        window.addEventListener('keyup', this.onDocumentKeyUp)

        // window.addEventListener('dblclick', this.onDblclick)

        const that = this
        container = document.getElementById('container')
        // container.addEventListener('click', this.transformControlsRemove, false)

        editor = new Editor(container, url)
        editor.scene.renderer.domElement.style.outline = 'none'
        container.appendChild(editor.scene.renderer.domElement)
        that.animate()
        editor.model.loadModel()
        editor.scene.controls.enabled = false
        let modelLoadInterval = setInterval(() => {
          if (editor.model) {
            clearInterval(modelLoadInterval)
          }
        }, 100)
        that.initModel()
        that.initScenario()
        // that.initTransformControl()
      },
      handleSelect (key, keyPath) {
        console.log(key, keyPath)
      },
      lineClick (key) {

        window.addEventListener('pointermove', this.onPointerMove, false)
        window.addEventListener('click', this.onPointerClick, false)
        window.removeEventListener('dblclick', this.onControlClick, false)
        this.msg = key

        editor.scene.camera.position.set(0, 1100, 0)//设置相机位置
        editor.scene.camera.lookAt(0, 0, 0)
        editor.scene.controls.enabled = false

        this.drawLine()

        //删除几何体
        this.removeModel()

      },
      drawLine(){
        let allChildren = editor.scene.scene.children
        for (let i = allChildren.length - 1; i >= 0; i--) {
          if (allChildren[i] instanceof THREE.Group && allChildren[i].name == 'lineGroup') {
            return
          }
        }

        console.log(222)
        let lineColor=null
        console.log(wall)
        wall.forEach(item=>{
          console.log(item)
          let geometry = new THREE.Geometry()
          geometry.vertices.push(item.lineData.point_1)
          geometry.vertices.push(item.lineData.point_2)
          let line = new THREE.Line(geometry, new THREE.LineDashedMaterial({
            color: 0x00FFFF,
            scale: 0
          }))
          line.computeLineDistances()
          lineGroup.add(line)
          if(item.lineSet.length>0){
            item.lineSet.forEach(item2=>{
              if (item2.key == '2') {
                lineColor = 0xd71345
              } else if (item2.key == '3') {
                lineColor = 0xFFFF00
              }
              let geometry = new THREE.Geometry()
              geometry.vertices.push(item2.point_1)
              geometry.vertices.push(item2.point_2)
              let line = new THREE.Line(geometry, new THREE.LineDashedMaterial({
                color: lineColor,
                scale: 0
              }))
              line.computeLineDistances()
              lineGroup.add(line)
            })
          }
        })
        editor.scene.scene.add(lineGroup)

      },
      removeModel () {
        let allChildren = editor.scene.scene.children
        for (let i = allChildren.length - 1; i >= 0; i--) {
          if (allChildren[i] instanceof THREE.Group && allChildren[i].name == 'theDoorGroup') {
            editor.scene.scene.remove(allChildren[i])
          }
        }

        let allChildren2 = theDoorGroup.children
        for (let i = allChildren2.length - 1; i >= 0; i--) {
          theDoorGroup.remove(allChildren2[i])
        }

      },
      dragModel () {
        window.addEventListener('dblclick', this.onControlClick, false)
        window.removeEventListener('pointermove', this.onPointerMove, false)
        window.removeEventListener('click', this.onPointerClick, false)
        this.drawer = true
      },
      textureMapping () {
        window.removeEventListener('pointermove', this.onPointerMove, false)
        window.removeEventListener('click', this.onPointerClick, false)
        // window.removeEventListener('dblclick', this.onControlClick, false)
        this.drawer2 = true
        console.log(editor.scene.scene)

      },
      textureMappingUrl (url) {
        console.log(url)
        textureUrl = url
      },
      textureMappingModel (ev) {
        ev.preventDefault()
        let getBoundingClientRect = container.getBoundingClientRect()
        // 屏幕坐标转标准设备坐标
        let x = ((event.clientX - getBoundingClientRect.left) / container.offsetWidth) * 2 - 1// 标准设备横坐标
        let y = -((event.clientY - getBoundingClientRect.top) / container.offsetHeight) * 2 + 1// 标准设备纵坐标
        let standardVector = new THREE.Vector3(x, y, 1)// 标准设备坐标
        // 标准设备坐标转世界坐标
        let worldVector = standardVector.unproject(editor.scene.camera)
        // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
        let ray = worldVector.sub(editor.scene.camera.position).normalize()
        // 创建射线投射器对象
        let rayCaster = new THREE.Raycaster(editor.scene.camera.position, ray)
        // 返回射线选中的对象 第二个参数如果不填 默认是false
        let intersects = rayCaster.intersectObjects(editor.scene.scene.children, true)

        if (intersects.length > 0) {
          console.log(intersects)
          if (intersects[0].object.name == 'thrDoor') {
            let texture = new THREE.TextureLoader().load(textureUrl)
            let mail = new THREE.MeshLambertMaterial({ map: texture })
            intersects[0].object.material = mail

            // this.$forceUpdate()
          }
        }
      },
      handleClose (done) {
        MessageBox.confirm('确认关闭？')
          .then(_ => {
            done()
          })
          .catch(_ => {
          })
      },
      initTransformControl () {
        transformControls = new TransformControls(editor.scene.camera, editor.scene.renderer.domElement)
        transformControls.name = 'transformControls'
        editor.scene.scene.add(transformControls)
        transformControls.addEventListener('mouseDown', function (event) {
          editor.scene.controls.enabled = false
        })
        transformControls.addEventListener('mouseUp', function (event) {
          editor.scene.controls.enabled = true
        })

      },
      //生成几何体
      generateBox () {
        window.addEventListener('dblclick', this.onControlClick, false)
        window.removeEventListener('pointermove', this.onPointerMove, false)
        window.removeEventListener('click', this.onPointerClick, false)
        editor.scene.controls.enabled = true
        //生成几何体
        for (let i = 0; i < wall.length; i++) {
          if (wall[i].lineSet.length == 0) {
            this.drawLineBox(wall[i].lineData.point_1, wall[i].lineData.point_2, 150)
          } else {
            this.drawLineBoxTheDoor(wall[i])
          }
        }

        //删除线条
        this.removeLine()
        console.log(editor.scene.scene)
      },
      removeLine(){
        let allChildren = editor.scene.scene.children
        for (let i = allChildren.length - 1; i >= 0; i--) {
          if (allChildren[i] instanceof THREE.Group && allChildren[i].name == 'lineGroup') {
            editor.scene.scene.remove(allChildren[i])
          }
        }

        let allChildren2 = lineGroup.children
        for (let i = allChildren2.length - 1; i >= 0; i--) {
          lineGroup.remove(allChildren2[i])
        }
      },
      //
      drawLineBox (start, end, height) {
        var d = this.createCylinderByTwoPoints(start, end, height)
        d.name = 'thrDoor'
        theDoorGroup.add(d)
        editor.scene.scene.add(theDoorGroup)
      },
      //根据两个坐标，生成几何体
      createCylinderByTwoPoints (vstart, vend, vheight) {
        var HALF_PI = Math.PI * .5

        //vstart坐标到vend坐标的间距
        var distance = vstart.distanceTo(vend)
        var position = vend.clone().add(vstart).divideScalar(2)

        var material = new THREE.MeshLambertMaterial({
          map: texture
        })
        var cylinder = new THREE.BoxGeometry(25, distance + 25, vheight)

        var orientation = new THREE.Matrix4()
        var offsetRotation = new THREE.Matrix4()
        var offsetPosition = new THREE.Matrix4()
        orientation.lookAt(vstart, vend, new THREE.Vector3(0, 5, 0))
        offsetRotation.makeRotationX(HALF_PI)
        orientation.multiply(offsetRotation)
        cylinder.applyMatrix(orientation)

        var mesh = new THREE.Mesh(cylinder, material)
        mesh.position.set(position.x, vheight / 2, position.z)
        return mesh
      },
      drawLineBoxTheDoor (arr) {

        var HALF_PI = Math.PI * .5

        //vstart坐标到vend坐标的间距
        var distance = arr.lineData.point_1.distanceTo(arr.lineData.point_2)
        console.log(distance)
        var position = arr.lineData.point_2.clone().add(arr.lineData.point_1).divideScalar(2)

        var material = new THREE.MeshLambertMaterial({
          map: texture
        })

        var cylinder = new THREE.BoxGeometry(25, distance + 25, 150)

        // //墙1
        var orientation = new THREE.Matrix4()
        var offsetRotation = new THREE.Matrix4()

        orientation.lookAt(arr.lineData.point_1, arr.lineData.point_2, new THREE.Vector3(0, 5, 0))
        offsetRotation.makeRotationX(HALF_PI)
        orientation.multiply(offsetRotation)
        cylinder.applyMatrix(orientation)
        var mesh = new THREE.Mesh(cylinder, material)
        mesh.position.set(position.x, 150 / 2, position.z)
        // editor.scene.scene.add(mesh)

        let result
        for (let i = 0; i < arr.lineSet.length; i++) {
          var distance2 = arr.lineSet[i].point_1.distanceTo(arr.lineSet[i].point_2)
          var position2 = arr.lineSet[i].point_2.clone().add(arr.lineSet[i].point_1).divideScalar(2)

          let hData
          if (arr.lineSet[i].key == '2') {
            hData = 120
          } else if (arr.lineSet[i].key == '3') {
            hData = 70
          }

          var cylinder2 = new THREE.BoxGeometry(25, distance2 + 25, hData)

          // //墙2
          orientation.lookAt(arr.lineSet[i].point_1, arr.lineSet[i].point_2, new THREE.Vector3(0, 5, 0))
          offsetRotation.makeRotationX(HALF_PI)
          orientation.multiply(offsetRotation)
          cylinder2.applyMatrix(orientation)
          var mesh2 = new THREE.Mesh(cylinder2, material)
          mesh2.position.set(position2.x, arr.lineSet[i].key == '2' ? hData / 2 : hData, position2.z)

          if (arr.lineSet[i].key == '2') {
            if (distance2 == 50) {
              //门
              orientation.lookAt(arr.lineSet[i].point_1, arr.lineSet[i].point_2, new THREE.Vector3(0, 5, 0))
              offsetRotation.makeRotationY(HALF_PI)
              orientation.multiply(offsetRotation)
              let theDoorData = modelArr[0].clone()
              theDoorData.applyMatrix(orientation)
              theDoorData.position.set(position2.x, position2.y, position2.z)
              theDoorGroup.add(theDoorData)
              editor.scene.scene.add(theDoorGroup)
            } else if (distance2 == 75) {
              orientation.lookAt(arr.lineSet[i].point_1, arr.lineSet[i].point_2, new THREE.Vector3(0, 5, 0))
              offsetRotation.makeRotationY(HALF_PI)
              orientation.multiply(offsetRotation)
              let theDoorData = modelArr[1].clone()
              theDoorData.applyMatrix(orientation)
              theDoorData.position.set(position2.x, position2.y, position2.z)
              theDoorGroup.add(theDoorData)
              editor.scene.scene.add(theDoorGroup)
            }
          } else if (arr.lineSet[i].key == '3') {
            if (distance2 == 75) {
              //窗
              orientation.lookAt(arr.lineSet[i].point_1, arr.lineSet[i].point_2, new THREE.Vector3(0, 5, 0))
              offsetRotation.makeRotationY(HALF_PI)
              orientation.multiply(offsetRotation)
              let windowData = modelArr[2].clone()
              windowData.applyMatrix(orientation)

              windowData.position.set(position2.x, 70, position2.z)
              theDoorGroup.add(windowData)
              editor.scene.scene.add(theDoorGroup)
            }
          }

          //挖洞
          const sphereBSP = new ThreeBSP(mesh)
          const cubeBSP = new ThreeBSP(mesh2)
          const resultBSP = sphereBSP.subtract(cubeBSP)
          result = resultBSP.toMesh()
          result.geometry.computeFaceNormals()
          result.geometry.computeVertexNormals()
          const material3 = new THREE.MeshPhongMaterial({ map: texture })
          result.material = material3
          mesh = result
          mesh.name = 'thrDoor'
        }
        theDoorGroup.add(mesh)
        editor.scene.scene.add(theDoorGroup)

      },
      //初始化
      initScenario () {
        //创建一个地板，如果只有网格，不能得到点击位置的坐标
        let geometry = new THREE.PlaneGeometry(1000, 1000)
        geometry.rotateX(-Math.PI / 2)
        let mail = new THREE.MeshBasicMaterial({ visible: false })
        let plane = new THREE.Mesh(geometry, mail)
        plane.name = 'Plane'
        plane.position.y = 1
        plane.receiveShadow = true
        editor.scene.scene.add(plane)
        objects.push(plane)

        //射线
        raycaster = new THREE.Raycaster()

        //红色方块
        const rollOverGeo = new THREE.PlaneBufferGeometry(25, 25)
        rollOverMaterial = new THREE.MeshLambertMaterial({
          color: 0xff0000,
          opacity: 0.5,
          transparent: true,
        })
        rollOverMesh = new THREE.Mesh(rollOverGeo, rollOverMaterial)
        rollOverMesh.rotateX(-Math.PI / 2)
        rollOverMesh.name = ''
        editor.scene.scene.add(rollOverMesh)

        //网格
        var gridHelper = new THREE.GridHelper(1000, 40)
        editor.scene.scene.add(gridHelper)

        //鼠标的二维坐标，在归一化的设备坐标(NDC)中，也就是X 和 Y 分量应该介于 -1 和 1 之间。
        pointer = new THREE.Vector2()

      },
      initModel () {
        new FBXLoader().load('http://localhost:3000/file/getFile/three/theDoor/theDoor.FBX', fbx => {
          fbx.scale.set(0.85, 0.85, 0.6)
          fbx.name = 'theDoor'
          fbx.rotation.x = -0.5 * Math.PI
          fbx.position.x = 100
          modelArr[0] = fbx
          // editor.scene.scene.add(fbx)
        })

        new FBXLoader().load('http://localhost:3000/file/getFile/three/theDoor/theDoor2.FBX', fbx => {
          fbx.scale.set(0.56, 0.59, 0.6)
          fbx.name = 'theDoor2'
          modelArr[1] = fbx
          // editor.scene.scene.add(fbx)
        })

        new GLTFLoader().load('http://localhost:3000/file/getFile/three/window/window.gltf', gltf => {
          gltf.scene.scale.set(0.37, 0.37, 0.37)
          gltf.scene.name = 'window'
          gltf.scene.rotation.x = -0.5 * Math.PI
          modelArr[2] = gltf.scene
          // editor.scene.scene.add(windowModel)
        })

        new FBXLoader().load('http://localhost:3000/file/getFile/three/table/table1/table.fbx', fbx => {
          fbx.scale.set(1.9, 1.9, 1.9)
          fbx.rotation.x = 0.5 * Math.PI
          fbx.name = 'table'
          fbx.position.y = 26
          modelArr[3] = fbx
          // editor.scene.scene.add(fbx)
        })

        new FBXLoader().load('http://localhost:3000/file/getFile/three/table/table2/table.FBX', fbx => {
          fbx.scale.set(0.8, 0.8, 0.8)
          fbx.name = 'table'
          modelArr[4] = fbx
          // editor.scene.scene.add(fbx)
        })

        new GLTFLoader().load('http://localhost:3000/file/getFile/three/sofa/sofa1/2738.gltf', gltf => {
          gltf.scene.scale.set(90, 90, 90)
          gltf.scene.name = 'sofa'
          modelArr[5] = gltf.scene
          // editor.scene.scene.add(gltf.scene)
        })

        new GLTFLoader().load('http://localhost:3000/file/getFile/three/airConditioner/airConditioner1/60.gltf', gltf => {
          gltf.scene.scale.set(60, 60, 60)
          gltf.scene.name = 'airConditioner'
          modelArr[6] = gltf.scene
          // editor.scene.scene.add(gltf.scene)
        })

        texture = new THREE.TextureLoader().load('http://localhost:3000/file/getFile/three/img/wallImg/2.jpeg')
      },
      controlModeClick (name) {
        if (transformControls == null) {
          return
        }
        if (name == '移动') {
          transformControls.setMode('translate')
        } else if (name == '旋转') {
          transformControls.setMode('rotate')
        } else if (name == '缩放') {
          transformControls.setMode('scale')
        } else if (name == '取消') {
          this.transformControlsRemove()
        }
      },
      createMesh (geom) {
        //  创建一个线框纹理
        const wireFrameMat = new THREE.MeshBasicMaterial({
          opacity: 0.5,
          wireframeLinewidth: 0.5,
          color: 0x70dbdb
        })
        //wireFrameMat.wireframe = true

        // 创建模型
        const mesh = new THREE.Mesh(geom, wireFrameMat)

        return mesh
      },
      //滑动执行
      onPointerMove (event) {

        if (this.msg == '1') {
          color = 0x00FFFF
        } else if (this.msg == '2') {
          color = 0xd71345
        } else if (this.msg == '3') {
          color = 0xFFFF00
        } else if (this.msg == '4') {
          color = 0x1A1A1A
        } else {
          color = 0x00FFFF
        }

        //ray因为屏幕有侧边栏，位置偏移问题
        let getBoundingClientRect = container.getBoundingClientRect()
        pointer.set(((event.clientX - getBoundingClientRect.left) / container.offsetWidth) * 2 - 1, -((event.clientY - getBoundingClientRect.top) / container.offsetHeight) * 2 + 1)
        raycaster.setFromCamera(pointer, editor.scene.camera)
        const intersects = raycaster.intersectObjects(objects)

        if (intersects.length > 0) {
          const intersect = intersects[0]
          rollOverMesh.position.copy(intersect.point).add(intersect.face.normal)
          rollOverMesh.position.divideScalar(25).floor().multiplyScalar(25).addScalar(12.5)
          rollOverMesh.position.y = 1

          point2.copy(intersect.point).add(intersect.face.normal)
          point2.divideScalar(25).floor().multiplyScalar(25).addScalar(12.5)
          point2.y = 0

          if (cnt == 1) {
            if (tempLine) {
              editor.scene.scene.remove(tempLine)
            }
            var geometry = new THREE.Geometry()
            geometry.vertices.push(point1)
            geometry.vertices.push(point2)
            tempLine = new THREE.Line(geometry, new THREE.LineDashedMaterial({
              color: color,
              scale: 0.1
            }))
            tempLine.computeLineDistances()
            editor.scene.scene.add(tempLine)
          }

        }
        this.render()
      },
      //画线
      onPointerClick (event) {

        //ray因为屏幕有侧边栏，位置偏移问题
        let getBoundingClientRect = container.getBoundingClientRect()
        pointer.set(((event.clientX - getBoundingClientRect.left) / container.offsetWidth) * 2 - 1, -((event.clientY - getBoundingClientRect.top) / container.offsetHeight) * 2 + 1)
        raycaster.setFromCamera(pointer, editor.scene.camera)

        if (tempLine && cnt == 1) {
          editor.scene.scene.remove(tempLine)
        }
        const intersects = raycaster.intersectObjects(objects)

        this.transformControlsRemove()
        if (intersects.length > 0) {

          const intersect = intersects[0]
          if (event.button == 0) {
            if (isShiftDown) {
              if (intersect.object !== plane) {
                editor.scene.scene.remove(intersect.object)
                objects.splice(objects.indexOf(intersect.object), 1)
              }

            } else {
              //点击位置生成预制几何体
              // const voxel = new THREE.Mesh(cubeGeo, cubeMaterial)
              // voxel.position.copy(intersect.point).add(intersect.face.normal)
              // voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25)
              // editor.scene.scene.add(voxel)
              // objects.push(voxel)

              switch (cnt) {
                case 0:
                  point1.copy(intersect.point).add(intersect.face.normal)
                  point1.divideScalar(25).floor().multiplyScalar(25).addScalar(12.5)
                  point1.y = 0
                  break
                case 1:
                  point2.copy(intersect.point).add(intersect.face.normal)
                  point2.divideScalar(25).floor().multiplyScalar(25).addScalar(12.5)
                  point2.y = 0

                  var geometry = new THREE.Geometry()
                  geometry.vertices.push(point1)
                  geometry.vertices.push(point2)
                  var line = new THREE.Line(geometry, new THREE.LineDashedMaterial({
                    color: color,
                    scale: 0
                  }))
                  line.computeLineDistances()
                  lineGroup.add(line)
                  editor.scene.scene.add(lineGroup)
                  objects.push(line)

                  var a = new coordinates()
                  a.point_1.copy(point1)
                  a.point_2.copy(point2)
                  a.key = this.msg ? this.msg : '1'
                  let lineSet = []
                  if (this.msg == '1') {
                    wall.push({
                      lineData: a,
                      lineSet: lineSet
                    })
                  } else if (this.msg == '2' || this.msg == '3') {

                    var distance = a.point_1.distanceTo(a.point_2)

                    if(this.msg == '2'){
                      if (distance == 75 || distance == 50) {
                        if (wall.length > 0) {
                          for (let i = 0; i < wall.length; i++) {
                            let list = this.parallelLine(wall[i], a)
                            if (list == 1) {
                              wall[i].lineSet.push(a)
                            }
                          }
                        }
                      }
                    }else if(this.msg == '3'){
                      if (distance == 75) {
                        if (wall.length > 0) {
                          for (let i = 0; i < wall.length; i++) {
                            let list = this.parallelLine(wall[i], a)
                            if (list == 1) {
                              wall[i].lineSet.push(a)
                            }
                          }
                        }
                      }
                    }


                  }else if (this.msg == '4') {
                    console.log(wall)
                    console.log(a)
                    if (wall.length > 0) {
                      for (let i = wall.length-1; i >= 0; i--) {
                        console.log(wall[i])
                        if(wall[i].lineData.point_1.x==a.point_1.x&&wall[i].lineData.point_1.y==a.point_1.y&&wall[i].lineData.point_1.z==a.point_1.z   &&   wall[i].lineData.point_2.x==a.point_2.x&&wall[i].lineData.point_2.y==a.point_2.y&&wall[i].lineData.point_2.z==a.point_2.z){
                          console.log(111)
                          wall.splice(i,1)
                          console.log(wall)
                        }
                      }
                    }
                  } else {
                    wall.push({
                      lineData: a,
                      lineSet: lineSet
                    })
                  }
                  break
              }

              cnt = (cnt + 1) % 2
            }
            this.render()
          }
        }
      },
      //选择添加家具
      loadingModel (ev) {
        ev.preventDefault()
        let getBoundingClientRect = container.getBoundingClientRect()
        // 屏幕坐标转标准设备坐标
        let x = ((event.clientX - getBoundingClientRect.left) / container.offsetWidth) * 2 - 1// 标准设备横坐标
        let y = -((event.clientY - getBoundingClientRect.top) / container.offsetHeight) * 2 + 1// 标准设备纵坐标
        let standardVector = new THREE.Vector3(x, y, 1)// 标准设备坐标
        // 标准设备坐标转世界坐标
        let worldVector = standardVector.unproject(editor.scene.camera)
        // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
        let ray = worldVector.sub(editor.scene.camera.position).normalize()
        // 创建射线投射器对象
        let rayCaster = new THREE.Raycaster(editor.scene.camera.position, ray)
        // 返回射线选中的对象 第二个参数如果不填 默认是false
        let intersects = rayCaster.intersectObjects(editor.scene.scene.children, true)

        if (intersects.length > 0) {
          if (intersects[0].object.name == 'Plane') {
            let furniture = modelArr[modelKey].clone()
            furniture.position.set(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z)
            dragModelGroup.add(furniture)
            editor.scene.scene.add(dragModelGroup)
            modelKey = null

            // this.$forceUpdate()
          }
        }
      },
      //双击，控制
      onControlClick (ev) {
        ev.preventDefault()
        let getBoundingClientRect = container.getBoundingClientRect()
        // 屏幕坐标转标准设备坐标
        let x = ((event.clientX - getBoundingClientRect.left) / container.offsetWidth) * 2 - 1// 标准设备横坐标
        let y = -((event.clientY - getBoundingClientRect.top) / container.offsetHeight) * 2 + 1// 标准设备纵坐标
        let standardVector = new THREE.Vector3(x, y, 1)// 标准设备坐标
        // 标准设备坐标转世界坐标
        let worldVector = standardVector.unproject(editor.scene.camera)
        // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
        let ray = worldVector.sub(editor.scene.camera.position).normalize()
        // 创建射线投射器对象
        let rayCaster = new THREE.Raycaster(editor.scene.camera.position, ray)
        // 返回射线选中的对象 第二个参数如果不填 默认是false
        let intersects = rayCaster.intersectObjects(editor.scene.scene.children, true)
        this.transformControlsRemove()

        if (intersects.length > 0) {

          if (intersects[0].object.name == 'AM109_049_01') {

            let a = rotateArr.some(item => {
              return item == intersects[0].object.name
            })

            if (a) {
              intersects[0].object.rotateZ(-Math.PI / 2)
              for (let i = 0; i < rotateArr.length; i++) {
                if (rotateArr[i] == intersects[0].object.name) {
                  rotateArr.splice(i, 1)
                  break
                }
              }
            } else {
              intersects[0].object.rotateZ(Math.PI / 2)
              rotateArr.push(intersects[0].object.name)
            }
          } else if (intersects[0].object.name == 'AM109_048_01' || intersects[0].object.name == 'AM109_048_02') {//双开门
            if (intersects[0].object.name == 'AM109_048_01') {
              let a = rotateArr.some(item => {
                return item == intersects[0].object.name
              })

              if (a) {
                intersects[0].object.rotateZ(-Math.PI / 2)
                for (let i = 0; i < rotateArr.length; i++) {
                  if (rotateArr[i] == intersects[0].object.name) {
                    rotateArr.splice(i, 1)
                    break
                  }
                }
              } else {
                intersects[0].object.rotateZ(Math.PI / 2)
                rotateArr.push(intersects[0].object.name)
              }
            } else {
              let a = rotateArr.some(item => {
                return item == intersects[0].object.name
              })

              if (a) {
                intersects[0].object.rotateZ(Math.PI / 2)
                for (let i = 0; i < rotateArr.length; i++) {
                  if (rotateArr[i] == intersects[0].object.name) {
                    rotateArr.splice(i, 1)
                    break
                  }
                }
              } else {
                intersects[0].object.rotateZ(-Math.PI / 2)
                rotateArr.push(intersects[0].object.name)
              }
            }
          } else if (intersects[0].object.name == 'mesh_1_18' || intersects[0].object.name == 'mesh_2_18') {//窗
            if (intersects[0].object.name == 'mesh_1_18') {
              let a = rotateArr.some(item => {
                return item == intersects[0].object.name
              })
              if (a) {
                intersects[0].object.parent.parent.children[1].position.x = 0
                for (let i = 0; i < rotateArr.length; i++) {
                  if (rotateArr[i] == intersects[0].object.name) {
                    rotateArr.splice(i, 1)
                    break
                  }
                }
              } else {
                intersects[0].object.parent.parent.children[1].position.x = -110
                rotateArr.push(intersects[0].object.name)
              }
            } else {
              let a = rotateArr.some(item => {
                return item == intersects[0].object.name
              })
              if (a) {
                intersects[0].object.parent.parent.children[2].position.x = 0
                for (let i = 0; i < rotateArr.length; i++) {
                  if (rotateArr[i] == intersects[0].object.name) {
                    rotateArr.splice(i, 1)
                    break
                  }
                }
              } else {
                intersects[0].object.parent.parent.children[2].position.x = 110
                rotateArr.push(intersects[0].object.name)
              }
            }
          } else if (intersects[0].object.name !== 'Plane'&&intersects[0].object.name !== 'thrDoor') {
            this.initTransformControl()

            // if(intersects[0].object.parent.parent.name=="table"){
            //   transformControls.attach(intersects[0].object.parent.parent)
            //   return
            // }

            transformControls.attach(intersects[0].object.parent)
          }
        }
      },
      //因为transformControls会让ray点击出现问题，所以不用的时候要把它移除
      transformControlsRemove () {

        if (transformControls != null) {
          transformControls.detach()
        }

        transformControls = null

        let allChildren = editor.scene.scene.children
        for (let i = 0; i < allChildren.length; i++) {
          if (allChildren[i].name == 'transformControls') {
            editor.scene.scene.remove(allChildren[i])
            editor.scene.scene.dispose(allChildren[i])
          }
        }
        this.radio = '移动'
      },
      passKey (key) {
        modelKey = key
      },
      onDocumentKeyDown (event) {
        switch (event.keyCode) {
          case 16:
            isShiftDown = true
            break

        }

      },
      onDocumentKeyUp (event) {
        switch (event.keyCode) {
          case 16:
            isShiftDown = false
            break

        }

      },
      render () {
        editor.scene.renderer.render(editor.scene.scene, editor.scene.camera)
      },
      animate () {
        let that = this
        renders = requestAnimationFrame(that.animate) //请求再次执行渲染函数render
        editor.scene.renderer.render(editor.scene.scene, editor.scene.camera)//执行渲染操作
      },

      //求两条线是否共线
      parallelLine (one, two) {
        let x = one.lineData.point_2.x - one.lineData.point_1.x
        let y = one.lineData.point_2.z - one.lineData.point_1.z

        let x2 = two.point_2.x - two.point_1.x
        let y2 = two.point_2.z - two.point_1.z

        let k1 = x * y2 - y * x2

        let v1 = two.point_2.x - one.lineData.point_1.x
        let v2 = two.point_2.z - one.lineData.point_1.z

        let k2 = v1 * y2 - v2 * x2

        let obj = {}
        if (k1 == 0 && k2 == 0) {
          return 1
        } else {
          return 0
        }
      },
      //屏幕适应
      onWindowResize () {
        editor.scene.camera.aspect = container.clientWidth / container.clientHeight
        editor.scene.camera.updateProjectionMatrix()
        editor.scene.renderer.setSize(container.clientWidth, container.clientHeight)
      },
      //删除模型
      initDispose () {
        let that = this
        if (editor.scene.scene) {
          let allChildren = editor.scene.scene.children.filter(x => x)
          allChildren.forEach(a => {
            that.dispose(editor.scene.scene, a)
          })
          editor.scene.scene.dispose()
          editor.scene.scene.remove()
          editor.scene.renderer.dispose()
          editor.scene.renderer.forceContextLoss()
          editor.scene.renderer.content = null
          editor.scene.renderer.domElement = null
          cancelAnimationFrame(renders)
        }

      },
      dispose (parent, child) {
        if (child.children.length) {
          let arr = child.children.filter(x => x)
          arr.forEach(obj => {
            this.dispose(child, obj)
          })
        }
        if (child.type === 'Mesh' || child.type === 'Line') {
          if (child.material.map) {
            if (child.material.map.dispose) {
              child.material.map.dispose()
            }
          }
          if (child.material.dispose) {
            child.material.dispose()
          }
          if (child.geometry.dispose) {
            child.geometry.dispose()
          }
        } else if (child.material) {
          if (child.material.dispose) {
            child.material.dispose()
          }
        }
        child.remove()
        parent.remove(child)
      },
    },
    destroyed () {
      this.initDispose()
    },
  }
</script>
<style scoped>
</style>
